package com.lengyu.vxminiprogram.security.rest;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lengyu.vxminiprogram.common.BaseConstant;
import com.lengyu.vxminiprogram.common.HttpResultDto;
import com.lengyu.vxminiprogram.common.HttpResultStatus;
import com.lengyu.vxminiprogram.security.exception.TokenException;
import com.lengyu.vxminiprogram.security.jwt.JwtUtils;
import com.lengyu.vxminiprogram.security.rest.dto.JwtUser;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JWTAuthorizationFilter extends BasicAuthenticationFilter {

    public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws IOException, ServletException {
        String header = request.getHeader(BaseConstant.Oauth.HEADER_PARAM.getVal());
        if (header == null || !header.startsWith(BaseConstant.Oauth.TOKEN_PREFIX.getVal())) {
            chain.doFilter(request, response);
            return;
            //请求头没有token则直接放行
        }
        //进行解析
        //先对header进行验证
        try {
            JwtUtils.validateJwt(header.replace(BaseConstant.Oauth.TOKEN_PREFIX.getVal(), ""));
        }catch (IllegalArgumentException e){
            if (e.getMessage().equals("JWT String argument cannot be null or empty.")){
//                ResultUtils.initResponse(response);
                response.getWriter().write(new ObjectMapper().writeValueAsString(HttpResultDto.failed(HttpResultStatus.TOKEN_VALID,"Token解析器解析失败,请携带正确的token")));
                return;
            }
        }
        catch (TokenException e){
            response.getWriter().write(new ObjectMapper().writeValueAsString(HttpResultDto.failed(HttpResultStatus.TOKEN_VALID,e.getMessage())));
            return;
        }

        SecurityContextHolder.getContext().setAuthentication(getAuthentication(header));
        super.doFilterInternal(request, response, chain);

    }

    private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader) {
        String token = tokenHeader.replace(BaseConstant.Oauth.TOKEN_PREFIX.getVal(), "");
        String user = JwtUtils.getJwtUser(token);
        JSONObject userObject = JSONObject.parseObject(user);
        if (user != null) {
            JwtUser jwtUser = JSONObject.toJavaObject(userObject,JwtUser.class);
            return new
                    UsernamePasswordAuthenticationToken(user, null, jwtUser.getAuthorities());
        }
        return null;
    }

}